home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C027B.ZIP / JAS / SCAN.C < prev    next >
Text File  |  1990-03-30  |  5KB  |  263 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15. #include "scan.h"
  16. #include "parse.h"
  17.  
  18. FILE *yyin;
  19. int lastc = 0;
  20. int ateof = 0;
  21. int do_star = 1;
  22.  
  23. getnext()
  24. {
  25.     static char buf[80];
  26.     static int cnt = 0, size = 0;
  27.     static last = '\n';
  28.     int sawstar = 0;
  29.     extern char *fgets();
  30.  
  31.     do {
  32.         while ( cnt >= size ) {
  33.             if ( fgets( buf, 80, yyin ) == (char *) NULL ) {
  34.                 return EOF;
  35.             }
  36.             size = strlen( buf );
  37.             cnt = 0;
  38.             if ( do_star && last == '\n' ) {
  39.                 while ( buf[cnt] &&
  40.                         (buf[cnt]==' '||buf[cnt]=='\t'))
  41.                     cnt++;
  42.                 if ( sawstar || buf[cnt] == '*' ) {
  43.                     sawstar = 1;
  44.                     while ( buf[cnt] && buf[cnt] != '\n' )
  45.                         cnt++;
  46.                 }
  47.             }
  48.         }
  49.         if (sawstar || (do_star && buf[cnt]=='\t' && buf[cnt+1]=='*')) {
  50.             sawstar = 1;
  51.             while ( buf[cnt] && buf[cnt] != '\n' )
  52.                 cnt++;
  53.         }
  54.     } while ( ! buf[cnt] );
  55.     return last = buf[cnt++];
  56. }
  57.  
  58. yygetc()
  59. {
  60.     register int c;
  61.  
  62.     if ( ateof )
  63.         return 0;
  64.     if ( lastc ) {
  65.         c = lastc;
  66.         lastc = 0;
  67.     } else
  68.         c = getnext();
  69.     if ( c && c != EOF ) {
  70.         return c;
  71.     }
  72.     ateof = 1;
  73.     return 0;
  74. }
  75.  
  76. yyungetc( c )
  77.     int c;
  78. {
  79.     if ( lastc ) {
  80.         char buf[32];
  81.         extern int line;
  82.  
  83.         sprintf( buf, "%c & %c pushed back!!", lastc, c );
  84.         error( line, buf );
  85.     }
  86.     lastc = c;
  87. }
  88.  
  89. yylex()
  90. {
  91.     register i;
  92.     int c;
  93.     struct lexacts *lp;
  94.     char buf[256];
  95.     extern YYSTYPE yylval;
  96.     extern int nwords;
  97.     extern struct lexacts actions[];
  98.     extern struct reserved words[];
  99.     extern INST *ifind();
  100.     extern SYM *lookup();
  101.  
  102.     for ( c = yygetc(); c; c = yygetc() ) {
  103.         lp = &actions[c];
  104.         if ( lp->acts & L_EXTRA ) {
  105.             i = yyprocess( c );
  106.             if ( i == COMMENT )
  107.                 continue;
  108.             else if ( i )
  109.                 return i;
  110.         }
  111.         if ( lp->acts & L_TOKEN ) {
  112.             return lp->retval;
  113.         }
  114.         if ( lp->acts & L_BEGID ) {
  115.             int tsz;
  116.             char *tbuf;
  117.             extern yywidth;
  118.  
  119.             for (i = 0; c && (actions[c].acts & L_MIDID); i++) {
  120.                 buf[i] = c;
  121.                 c = yygetc();
  122.             }
  123.             buf[i] = '\0';
  124.             if ( c )
  125.                 yyungetc( c );
  126.             tbuf = STRCPY( buf );
  127.             yymodify( tbuf );
  128.             yywidth = 0;
  129.  
  130.             tsz = strlen( tbuf );
  131.             if ( tsz >= 2 && tbuf[tsz-2] == '.' ) {
  132.                 switch ( tbuf[tsz-1] ) {
  133.                 case 'b':
  134.                     yywidth = 8;
  135.                     buf[tsz-2] = tbuf[tsz-2] = '\0';
  136.                     break;
  137.                 case 'w':
  138.                     yywidth = 16;
  139.                     buf[tsz-2] = tbuf[tsz-2] = '\0';
  140.                     break;
  141.                 case 'l':
  142.                     yywidth = 32;
  143.                     buf[tsz-2] = tbuf[tsz-2] = '\0';
  144.                     break;
  145.                 }
  146.             }
  147.             
  148.             {
  149.                 register int lo = 0;
  150.                 register int hi = nwords-2;
  151.                 register int d;
  152.                 register struct reserved *rp;
  153.  
  154.                 while ( lo <= hi ) {
  155.                     i = (lo + hi) / 2;
  156.                     rp = &words[i];
  157.                     d = strcmp( tbuf, rp->name );
  158.                     if (! strcmp( tbuf, rp->name ) ) {
  159.                         yylval.val = rp->value;
  160.                         free( tbuf );
  161.                         return rp->token;
  162.                     } else if ( d < 0 ) {
  163.                         hi = i-1;
  164.                     } else if ( d > 0 ) {
  165.                         lo = i+1;
  166.                     } else { /* wrong scope */
  167.                         break;
  168.                     }
  169.                 }
  170.             }
  171.             
  172.             /*
  173.              * if it's not a reserved word, put the length back
  174.              */
  175.             if ( yywidth != 0 )
  176.                 buf[tsz-2] = tbuf[tsz-2] = '.';
  177.  
  178.             {
  179.                 register STMT *sp;
  180.                 register INST *ip;
  181.                 short misc;
  182.  
  183.                 ip = ifind( tbuf, &misc );
  184.                 if ( ip != (INST *) NULL ) {
  185.                     sp = ALLO(STMT);
  186.                     sp->inst = ip;
  187.                     sp->misc = misc;
  188.                     free( tbuf );
  189.                     yylval.stmt = sp; 
  190.                     return INSTR;
  191.                 }
  192.             }
  193.  
  194.             free( tbuf );
  195.  
  196.             yylval.sym = lookup( buf );
  197.             return lp->retval;
  198.         }
  199.         if ( lp->acts & L_DIGIT ) {
  200.             extern long getnum();
  201.  
  202.             for (i = 0; c && (actions[c].acts & L_DIGIT); i++) {
  203.                 buf[i] = c;
  204.                 c = yygetc();
  205.             }
  206.             buf[i] = '\0';
  207.             if ( c )
  208.                 yyungetc( c );
  209.             yylval.val = getnum( buf );
  210.             return lp->retval;
  211.         }
  212.         /* L_SKIP */
  213.     }
  214.     return 0;
  215. }
  216.  
  217. long
  218. getnum( s )
  219.     register char *s;
  220. {
  221.     register long val;
  222.     register int base;
  223.  
  224.     switch ( *s ) {
  225.     case '$':
  226.         base = 16;
  227.         s++;
  228.         break;
  229.     case '0':
  230.     case '@':
  231.         base = 8;
  232.         s++;
  233.         break;
  234.     default:
  235.         base = 10;
  236.         break;
  237.     }
  238.  
  239.     for ( val = 0L; *s; s++ ) {
  240.         if ( *s >= '0' && *s <= '7' ) {
  241.             val = val * base + ( *s - '0' );
  242.         } else if ( *s >= '8' && *s <= '9' ) {
  243.             if ( base == 8 )
  244.                 Yerror( "invalid octal constant" );
  245.             val = val * base + ( *s - '0' );
  246.         } else if ( *s >= 'a' && *s <= 'f' ) {
  247.             if ( base == 8 )
  248.                 Yerror( "invalid octal constant" );
  249.             if ( base == 10 )
  250.                 Yerror( "invalid decimal constant" );
  251.             val = val * base + ( *s - 'a' + 10 );
  252.         } else /* if ( *s >= 'A' && *s <= 'F' ) */ {
  253.             if ( base == 8 )
  254.                 Yerror( "invalid octal constant" );
  255.             if ( base == 10 )
  256.                 Yerror( "invalid decimal constant" );
  257.             val = val * base + ( *s - 'A' + 10 );
  258.         }
  259.  
  260.     }
  261.     return val;
  262. }
  263.